package com.chenchen.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.chenchen.auth.common.enums.AuthUserStatusEnum;
import com.chenchen.auth.common.enums.IsDeletedFlagEnum;
import com.chenchen.auth.domain.constants.AuthConstant;
import com.chenchen.auth.domain.convert.AuthUserBOConverter;
import com.chenchen.auth.domain.entity.AuthUserBO;
import com.chenchen.auth.domain.redis.RedisUtil;
import com.chenchen.auth.domain.service.AuthUserDomainService;
import com.chenchen.auth.infra.basic.entity.*;
import com.chenchen.auth.infra.basic.service.*;
import com.google.gson.Gson;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private AuthRoleService authRoleService;

    private String salt = "chicken";

    @Resource
    private RedisUtil redisUtil;

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private static final String LOGIN_PREFIX = "loginCode";

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean register(AuthUserBO authUserBO) {
        //校验用户是否存在
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (existUser.size() > 0) {
            return true;
        }
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToEntity(authUserBO);
        if (!StringUtils.isBlank(authUser.getPassword())) {
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }
        if (!StringUtils.isBlank(authUser.getAvatar())) {
            authUser.setAvatar("http://117.72.10.84:9000/user/icon/微信图片_20231203153718(1).png");
        }
        if (StringUtils.isBlank(authUser.getNickName())) {
            authUser.setNickName("海问香");
        }
        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        Integer count = authUserService.insert(authUser);

        //建立一个初步的角色关联
        AuthRole authRole = new AuthRole(); // 创建一个新的AuthRole对象
        authRole.setRoleKey(AuthConstant.NORMAL_USER); // 设置角色键为普通用户
        AuthRole roleResult = authRoleService.queryByCondition(authRole); // 根据条件查询角色
        Long roleId = roleResult.getId(); // 获取角色ID
        Long userId = authUser.getId(); // 获取用户ID
        AuthUserRole authUserRole = new AuthUserRole(); // 创建一个新的AuthUserRole对象
        authUserRole.setRoleId(roleId); // 设置角色ID
        authUserRole.setUserId(userId); // 设置用户ID
        authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode()); // 设置是否删除标志为未删除
        // 插入用户角色关联记录
        authUserRoleService.insert(authUserRole);
        //将用户信息缓存到redis
        //将用户信息缓存到redis
        // 根据用户名和角色前缀，构建角色key
        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        // 创建角色列表，并将当前角色添加到列表中
        List<AuthRole> roleList = new LinkedList<>();
        roleList.add(authRole);
        // 将角色列表以json格式存入redis
        redisUtil.set(roleKey, new Gson().toJson(roleList));
        // 创建角色权限对象
        AuthRolePermission authRolePermission = new AuthRolePermission();
        // 设置角色id
        authRolePermission.setRoleId(roleId);
        // 根据角色权限对象，查询角色权限列表
        List<AuthRolePermission> rolePermissionList = authRolePermissionService
                .queryByCondition(authRolePermission);
        // 将角色权限列表中权限id收集到权限id列表中
        List<Long> permisstionIdList = rolePermissionList.stream()
                .map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
        // 根据权限id列表，查询权限列表
        List<AuthPermission> permissionList = authPermissionService.queryByRoleList(permisstionIdList);
        // 根据用户名和权限前缀，构建权限key
        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        // 将权限列表以json格式存入redis
        redisUtil.set(permissionKey, new Gson().toJson(permissionList));
        return count > 0;
    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToEntity(authUserBO);
        Integer count = authUserService.updateByUserName(authUser);
        return count > 0;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = new AuthUser();
        authUser.setId(authUserBO.getId());
        authUser.setIsDeleted(IsDeletedFlagEnum.DELETED.getCode());
        Integer count = authUserService.update(authUser);
        //有任何的更新，都要与缓存进行同步的修改
        return count > 0;
    }
    @Override
    public SaTokenInfo doLogin(String validCode) {
        // 获取登录key
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        // 从redis中获取openId
        String openId = redisUtil.get(loginKey);
        // 如果openId为空，则返回null
        if (StringUtils.isEmpty(openId)) {
            return null;
        }
        // 创建AuthUserBO对象
        AuthUserBO authUserBO = new AuthUserBO();
        // 设置用户名
        authUserBO.setUserName(openId);
        // 注册
        this.register(authUserBO);
        // 登录
        StpUtil.login(openId);
        // 获取tokenInfo
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        // 返回tokenInfo
        return tokenInfo;
    }

    /**
     * 获取用户信息
     * @param authUserBO
     * @return
     */
    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        //创建AuthUser对象
        AuthUser authUser = new AuthUser();
        //设置AuthUser的userName属性
        authUser.setUserName(authUserBO.getUserName());
        //调用authUserService的queryByCondition方法，根据条件查询AuthUser对象
        List<AuthUser> userList = authUserService.queryByCondition(authUser);
        //判断userList是否为空
        if (CollectionUtils.isEmpty(userList)) {
            //如果为空，返回一个新的AuthUserBO对象
            return new AuthUserBO();
        }
        //如果不为空，获取第一个AuthUser对象
        AuthUser user = userList.get(0);
        //返回AuthUserBOConverter转换后的AuthUserBO对象
        return AuthUserBOConverter.INSTANCE.convertEntityToBO(user);


    }

    /**
     * 根据用户名列表获取用户信息
     *
     * @param userNameList
     * @return
     */
    @Override
    public List<AuthUserBO> listUserInfoByIds(List<String> userNameList) {
        List<AuthUser> userList = authUserService.listUserInfoByIds(userNameList);
        if (CollectionUtils.isEmpty(userList)) {
            return Collections.emptyList();
        }
        return AuthUserBOConverter.INSTANCE.convertEntityToBO(userList);
    }

}
